package com.woniuxy.mini;

import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;
import com.woniuxy.config.AliChatService;
import com.woniuxy.config.ChatService;
import com.woniuxy.core.service.AIChatMessageService;
import com.woniuxy.core.service.AIChatSessionService;
import com.woniuxy.entity.AIChatMessage;
import com.woniuxy.entity.AIChatSession;
import com.woniuxy.entity.DTO.request.AudioMessageRequest;
import com.woniuxy.entity.DTO.request.SaveMessageRequest;
import com.woniuxy.entity.UploadResult;
import com.woniuxy.feign.OSSApi;
import com.woniuxy.util.ResponseData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;

import java.io.File;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/ai")
public class AIChatController {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private AIChatSessionService aiChatSessionService;
    @Autowired
    private ChatService chatService;
    @Autowired
    private AIChatMessageService aiChatMessageService;
    @Autowired
    AliChatService aliChatService;
    @Autowired
    private OSSApi ossApi;

    @PostMapping(value = "/aiServerChat/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> aiServerChatStream(@RequestBody SaveMessageRequest request) {
        List<String> range = stringRedisTemplate.opsForList().range("ai:history:" + request.getSessionId(), -10, -1);
        if (range == null && range.isEmpty()) {
            return chatService.aiServerChatStream(request.getUserInput());
        }
        String sessionHistory = String.join("\n", range);
        String message = "以下是历史对话：\n" + sessionHistory
                + "\n请仅回答用户的新问题：" + request.getUserInput()
                + "\nuserId:" + request.getUserId()
                + "\n注意：不要重复回答历史对话中已经回答过的问题。";
        return chatService.aiServerChatStream(message);
    }

    @GetMapping("/ai")
    String generation(@RequestParam("userInput") String userInput,
                      @RequestParam(value = "chatId",required = false) String chatId) {
//        return aiChatService.getChat(userInput,chatId);
        return chatService.processQuery(userInput);
    }
    //ai流式会话
    @PostMapping(value = "/chat/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> streamChat(@RequestBody SaveMessageRequest request) {
        List<String> range = stringRedisTemplate.opsForList().range("ai:history:"+request.getSessionId(), -10, -1);
        System.out.println("range"+range);
        if (range==null&&range.isEmpty()){
            return chatService.processQueryStream(request.getUserInput());
        }
        String sessionHistory = String.join("\n",range);
        String message = "以下是历史对话：\n" + sessionHistory
                + "\n请仅回答用户的新问题：" + request.getUserInput()
                + "\nuserId:" + request.getUserId()
                + "\n注意：结合历史对话回答但不要重复回答历史对话中已经回答过的问题。";
        return chatService.processQueryStream(message);
    }
    //AI语音指令
    @PostMapping("/audio")
    public Flux<String> audioChat(@RequestBody SaveMessageRequest request) throws NoApiKeyException, UploadFileException {
        List<String> range = stringRedisTemplate.opsForList().range("ai:history:"+request.getSessionId(), -10, -1);
        //获取音频文件路径
        String audioFile = request.getUserInput();
        //提取音频转入userInput
        request.setUserInput(aliChatService.simpleMultiModalConversationCall(audioFile));
        //判断是否为新的会话
        if (range==null&&range.isEmpty()){
            return chatService.processQueryStream(request.getUserInput());
        }
        String sessionHistory = String.join("\n",range);
        String message = "以下是历史对话：\n" + sessionHistory
                + "\n请仅回答用户的新问题：" + request.getUserInput()
                + "\nuserId:" + request.getUserId()
                + "\n注意：不要重复回答历史对话中已经回答过的问题。";
        return chatService.processQueryStream(message);
    }
    @PostMapping("/save")
    public ResponseData<String> saveMessage(@RequestBody SaveMessageRequest request) {
        System.out.println(request);
        // 1. 存储用户消息（无需检查会话是否存在）
        saveMessageToDbAndRedis(
                request.getSessionId(),
                request.getMessageId(),
                request.getUserId(),
                "user",
                request.getUserInput()
        );

        // 2. 存储AI响应
        saveMessageToDbAndRedis(
                request.getSessionId(),
                request.getMessageId(),
                request.getUserId(),
                "ai",
                request.getAiResponse()
        );

        return ResponseData.ok("保存成功");
    }
    // 存储消息的统一方法
    private void saveMessageToDbAndRedis(String sessionId, String msgId, Integer userId, String role, String content) {
        // 1. 构造消息对象
        AIChatMessage message = new AIChatMessage();
        message.setSessionId(sessionId);
        message.setMessageId(msgId);
        message.setUserId(userId);
        message.setRole(role);
        message.setContent(content);
        message.setCreatedAt(LocalDateTime.now());
        //构造会话对象
        AIChatSession session = new AIChatSession();
        //判断是否为第一次访问
        AIChatSession byId = aiChatSessionService.getById(sessionId);
        session.setUpdateTime(LocalDateTime.now());
        System.out.println("112131"+byId);
        if (byId == null){
            //此为第一次
            session.setUserId(userId);
            session.setSessionId(sessionId);
            session.setCreateTime(LocalDateTime.now());
            session.setUserInput(content);
        }else {
            //此为后续
            session.setUserId(userId);
            session.setSessionId(sessionId);
        }


        // 2. 异步存储到数据库
        CompletableFuture.runAsync(() -> {
            aiChatMessageService.save(message);
            System.out.println("message"+message);
            if (byId == null){
                //第一次
                aiChatSessionService.save(session); //创建
                String sessionMsgKey = "ai:session:" + userId.toString();
                stringRedisTemplate.opsForHash().put(sessionMsgKey,sessionId,session.getUserInput());
                stringRedisTemplate.expire(sessionMsgKey,7, TimeUnit.DAYS);
            }else {
                aiChatSessionService.updateById(session);// 更新会话时间
            }

        });

        // 3. 缓存到Redis
        stringRedisTemplate.executePipelined((RedisCallback<Object>) connection -> {
            // 定义日期格式化器
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            // 缓存消息内容
//            String msgKey = "ai:message:" + msgId;
//            stringRedisTemplate.opsForHash().put(msgKey,"sessionId",sessionId);
//            stringRedisTemplate.opsForHash().put(msgKey,"role",role);
//            stringRedisTemplate.opsForHash().put(msgKey,"content",content);
//            if (message.getCreatedAt() != null) {
//                stringRedisTemplate.opsForHash().put(msgKey, "createdAt", message.getCreatedAt().format(formatter));
//            }
//            stringRedisTemplate.expire(msgKey,7, TimeUnit.DAYS);

            // 添加到会话消息列表
//            String sessionMsgKey = "ai:session:" + sessionId;
//            stringRedisTemplate.opsForZSet().add(sessionMsgKey,msgId,message.getCreatedAt().toEpochSecond(ZoneOffset.UTC));
//            stringRedisTemplate.expire(msgKey,7, TimeUnit.DAYS);

            //ai历史记录
            String sessionKey = "ai:history:"+sessionId;
            stringRedisTemplate.opsForList().rightPush(sessionKey, message.getContent());
            stringRedisTemplate.expire(sessionKey,30, TimeUnit.DAYS);
            return null;
        });
    }

}
